package tools.webkit;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import tools.twitter.URLTools;

/**
 * URL Jumper which support Multi-Thread
 * 
 * @author Lanjun
 * 
 */
public class URLJumper {
	List<Webpage> webpages;
	private int pointer = 0;
	private int numOfThreads = 0;
	private final String BROWSER = "IE8.0";
	private int maxJumpTime = 10;

	private synchronized Webpage getOnePage() {
		if (pointer > (webpages.size() - 1)) {
			return null;
		}
		Webpage page = webpages.get(pointer);
		pointer++;
		return page;
	}

	class CrawlThread extends Thread {
		Pattern comment = Pattern.compile("<!\\s*--.*?--\\s*>", Pattern.DOTALL);

		public void run() {
			DownloadURL d = new DownloadURL();
			while (true) {
				Webpage p = getOnePage();
				if (p == null) {
					System.out.println("Thread " + this.getId() + " END!");
					break;
				} else {
					System.out.println("Thread " + this.getId()
							+ " is dealing: " + p.url);
					if (p.content == null) {
						continue;
					}
					// analyze the content to find the redirections. If there is
					// no redirections, return the original
					String newContent = p.content.toLowerCase();
					newContent = comment.matcher(newContent).replaceAll("");
					int currentJumpTime = 0;
					while (newContent != null
							&& newContent
									.contains("http-equiv=\"refresh\" content=\"0;url=")) {
						if (currentJumpTime >= maxJumpTime) {
							System.err.println("\t=>Thread " + this.getId()
									+ ": " + p.url + ", jumps more than "
									+ maxJumpTime + " times! Skipping...");
							break;
						}
						// redirection urls
						int start = newContent.indexOf("content=\"0;url=");
						int end = newContent.indexOf("\"", start + 15);
						String tempURL = p.content.substring(start + 15, end);
						tempURL = URLTools.getURL(tempURL, p.realURL);
						Webpage tempWP = d.downURL(tempURL, BROWSER);

						p.realURL = tempWP.realURL;
						System.out.println("\t=> Thread " + this.getId()
								+ " redirect: " + p.realURL);

						if (tempWP.content != null && p.content != null
								&& tempWP.content.equals(p.content)) {
							/*
							 * if the content is always the same. need not to be
							 * processed. In case of some stupid web sites
							 */
							break;
						}
						currentJumpTime++;
						p.content = tempWP.content;
						if (tempWP.content != null) {
							newContent = tempWP.content.toLowerCase();
							// delete all comments before jumping
							newContent = comment.matcher(newContent)
									.replaceAll("");
						} else {
							newContent = null;
						}
					}
					System.out.println("Thread " + this.getId() + ": " + p.url
							+ " !DONE!");
					try {
						sleep(200);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	/**
	 * initial
	 * 
	 * @param numOfThreads
	 *            At least 1
	 */
	public URLJumper(int numOfThreads) {
		if (numOfThreads < 1) {
			numOfThreads = 1;
		}
		this.numOfThreads = numOfThreads;
	}

	public List<Webpage> doJump(List<Webpage> webpages) {
		this.webpages = webpages;
		List<Thread> threadList = new ArrayList<Thread>();
		for (int i = 0; i < numOfThreads; i++) {
			Thread t = new CrawlThread();
			t.start();
			threadList.add(t);
		}

		for (int i = 0; i < numOfThreads; i++) {
			try {
				threadList.get(i).join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		return webpages;
	}

	public static void main(String[] args) {
		// try {
		// System.setOut(new PrintStream(new File("./logs/URLJumper.out.log")));
		// System.setErr(new PrintStream(new File("./logs/URLJumper.err.log")));
		// } catch (FileNotFoundException e) {
		// e.printStackTrace();
		// }
		// @SuppressWarnings("unchecked")
		// List<Webpage> w = (ArrayList<Webpage>)
		// ObjectTools.readFromFile("data/objs/urlContent1/9_11_memorial_2011.dat.dl1");
		List<Webpage> w = new ArrayList<>();
		Webpage wp = new Webpage();
		wp.url = "http://www.smileyandwest.com/";
		wp.realURL = "http://www.smileyandwest.com/";
		wp.content = "<!--[if lte IE 6]>\n <meta http-equiv=\"refresh\" content=\"0;url=http://www.smileyandwest.com/\" />\n<![endif]-->";
		w.add(wp);
		URLJumper u = new URLJumper(5);
		List<Webpage> returned = u.doJump(w);
		for (Webpage p : returned) {
			System.out.println(p.url);
			System.out.println(p.realURL);
		}
		// ObjectTools.writeToFile(returned,
		// "data/objs/urlContent2/9_11_memorial_2011.dat.dl1");

	}
}
